package benchmark;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;


public class FSObject extends AbstractMTTask {
	
	private class FSObjectCallable implements Callable<String> {

		Target target;
		int position;
		
		public FSObjectCallable(Target target, int position) {
			this.target = target;
			this.position = position;
		}

		@Override
		public String call() throws Exception {
			long counter = iterTime;
			while(counter-- > 0) {
				
				target.set(position, target.get(position) + counter);
			}
			return Long.toString(target.getSum());
		}
		
		
	}
	
	Target target;
	
	long iterTime;
	
	/*
	 * @param param
	 * 0. class name
	 * 1. thread number
	 * 2. stride
	 * 3. iteration time
	 */
	@Override
	protected List<Callable<String>> initCallables(List<String> param) {
		
		int stride = Integer.parseInt(param.get(2));
		iterTime = Long.parseLong(param.get(3));
		target = new Target();
		
		for (int i = 0; i < 21; i++) {
			target.set(i, i);
		}

		List<Callable<String>> l = new ArrayList<Callable<String>>();
		for (int i = 0; i < this.threadNum; i++) {
			l.add(new FSObjectCallable(target, stride * i));
		}
		return l;
	}

	private class Target {
		volatile long p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12;
//		volatile long p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20;
		
		long getSum() {
			long sum = 0;
			for (int i = 0; i < 14; i++) {
				sum += get(i);
			}
			return sum;
		}
		
		long get(int index) {
			long ret = 0;
			switch(index) {
			case 0:ret = p0;break;
			case 1:ret = p1;break;
			case 2:ret = p2;break;
			case 3:ret = p3;break;
			case 4:ret = p4;break;
			case 5:ret = p5;break;
			case 6:ret = p6;break;
			case 7:ret = p7;break;
			case 8:ret = p8;break;
			case 9:ret = p9;break;
			case 10:ret = p10;break;
			case 11:ret = p11;break;
			case 12:ret = p12;break;
//			case 13:ret = p13;break;
//			case 14:ret = p14;break;
//			case 15:ret = p15;break;
//			case 16:ret = p16;break;
//			case 17:ret = p17;break;
//			case 18:ret = p18;break;
//			case 19:ret = p19;break;
//			case 20:ret = p20;break;
			default:break;
			}
			return ret;
		}
		
		void set(int index, long value) {
			switch(index) {
			case 0:p0 = value;break;
			case 1:p1 = value;break;
			case 2:p2 = value;break;
			case 3:p3 = value;break;
			case 4:p4 = value;break;
			case 5:p5 = value;break;
			case 6:p6 = value;break;
			case 7:p7 = value;break;
			case 8:p8 = value;break;
			case 9:p9 = value;break;
			case 10:p10 = value;break;
			case 11:p11 = value;break;
			case 12:p12 = value;break;
//			case 13:p13 = value;break;
//			case 14:p14 = value;break;
//			case 15:p15 = value;break;
//			case 16:p16 = value;break;
//			case 17:p17 = value;break;
//			case 18:p18 = value;break;
//			case 19:p19 = value;break;
//			case 20:p20 = value;break;
			default:break;
			}
		}
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

}
